# coding=utf-8
"""
Handler for WeChat Official Account.
The url is /wx

2019-3-25 by Stone at GDOU-KC
"""
from flask import request
import re

import person
from wxAPI import message
from Handler import tags
import settings as st


# ===== ===== ===== =====
# Constants
# ===== ===== ===== =====
DFT_STR = u'无记录'  # default value fo empty record

PAT = ' '  # pattern to split command and parameter

# map the correspond feature to the cmd
CMD_MAP = {
    'sign_up_or_view': ['666', u'船模大赛', u'船模大賽'],
    'edit_info': ['E%i'%i for i in range(1, 6)]
}
# map cmd to the filed to edit
EDIT_MAP = {
    'E1': 'xuehao',
    'E2': 'name',
    'E3': 'phone_number',
    'E4': 'major_class',
    'E5': 'team_name',
}


# ===== ===== ===== =====
# Exceptions
# ===== ===== ===== =====
class ExceptionOpenIdUnbound(Exception):
    def __init__(self, *args, **kw):
        super(ExceptionOpenIdUnbound).__init__(self, *args, **kw)


def interface_wx():
    """The main entrance to handle the request flow."""
    data = request.data
    msg = message.parse_xml(data)
    open_id = msg.UserName_client
    tag = tags.add({'open_id': msg.UserName_client})

    cmd, para = parse_cmd(msg.data['Content'])
    if cmd in CMD_MAP['sign_up_or_view']:
        resp = sign_up_or_view(open_id, tag)

    elif cmd in CMD_MAP['edit_info']:
        resp = edit_info(open_id, cmd, para)

    else:
        resp = st.TXT_ERR_COMMAND_NO_FOUND

    msg.data['Content'] = resp
    return msg.render()


def check_has_open_id_bounded(open_id):
    """Search this OpenId in database to see if the user has signed up.
     Return the person instance when the record is found and return False
     when not found."""
    p = person.search_person('open_id', open_id)
    if person.search_person('open_id', open_id) is None:
        return False
    else:
        return p


def parse_cmd(text):
    """Parse the message sent by Wechat Official Account into the format
    of *cmd para*, by simply splitting the first spaces. If there is no
    space, return an empty string as parameter."""
    rslt = re.split(PAT, text, 1)
    try:
        return rslt[0], rslt[1]
    except IndexError:
        return rslt[0], ''


def sign_up_or_view(open_id, tag):
    p = check_has_open_id_bounded(open_id)
    if p:
        # Show the user's info if he has signed up
        resp = st.TXT_VIEW_INFO.format(
            xuehao=dft(p.xuehao),
            name=dft(p.name),
            phone_number=dft(p.phone_number),
            major_class=dft(p.major_class),
            team_name=dft(p.team_name)
        )
        return resp
    else:
        # Response the sign up url if he has not signed up
        return st.TXT_SIGN_UP_URL_PROMPT.format(tag=tag)


def edit_info(open_id, cmd, para):
    p = person.search_person('open_id', open_id)
    setattr(p, EDIT_MAP[cmd], para)
    p.save()

    return st.TXT_EDIT_SUCCESS


def dft(ss, default=DFT_STR):
    """If the string *ss* is empty, return the *default* passed in."""
    if ss == '':
        return default
    else:
        return ss

if __name__ == '__main__':
    t = tags.add('b')
